package org.springblade.modules.ad.config;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.pool.factory.PoolingContextSource;
import org.springframework.ldap.pool.validation.DefaultDirContextValidator;
import org.springframework.ldap.transaction.compensating.manager.TransactionAwareContextSourceProxy;

import java.util.HashMap;
import java.util.Map;

/**
 * LDAP 的自动配置类
 *
 * 完成连接LDAP 及LdapTemplate 的定义
 */
//@ConfigurationProperties(prefix = "ldaps")
//@PropertySource("classpath:/application.yml")
@Configuration
public class LdapConfiguration {
	private LdapTemplate ldapTemplate;

	@Value("${ldaps.maxActive}")
	private int maxActive;

	@Value(value = "${ldaps.maxTotal}")
	private int maxTotal;

	@Value(value = "${ldaps.maxIdle}")
	private int maxIdle;

	@Value(value = "${ldaps.minIdle}")
	private int minIdle;

	@Value(value = "${ldaps.maxWait}")
	private int maxWait;

	@Value(value = "${ldaps.urls}")
	private String LDAP_URL;

	@Value(value = "${ldaps.base}")
	private String BASE_DC;

	@Value(value = "${ldaps.username}")
	private String USER_NAME;

	@Value(value = "${ldaps.password}")
	private String PASS_WORD;

	@Value(value = "${ldaps.trustStore}")
	private String trustStore;

	@Value(value = "${ldaps.trustStorePassword}")
	private String trustStorePassword;


	@Bean
	public LdapContextSource contextSource() {
		LdapContextSource contextSource = new LdapContextSource();
		Map<String, Object> config = new HashMap();

		contextSource.setUrl(LDAP_URL);
		contextSource.setBase(BASE_DC);
		contextSource.setUserDn(USER_NAME);
		contextSource.setPassword(PASS_WORD);

		System.setProperty("javax.net.ssl.trustStore", trustStore);
		System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);

		//  解决 乱码 的关键一句
		config.put("java.naming.ldap.attributes.binary", "objectGUID");

		//当需要连接时，池是否一定创建新连接
		contextSource.setPooled(true);
		contextSource.setBaseEnvironmentProperties(config);
		return contextSource;
	}

	/**
	 * LDAP pool 配置
	 * @return
	 */
	@Bean
	public ContextSource poolingLdapContextSource() {
		PoolingContextSource poolingContextSource = new PoolingContextSource();
		poolingContextSource.setDirContextValidator(new DefaultDirContextValidator());
		poolingContextSource.setContextSource(contextSource());
		poolingContextSource.setTestOnBorrow(true);//在从对象池获取对象时是否检测对象有效
		poolingContextSource.setTestWhileIdle(true);//在检测空闲对象线程检测到对象不需要移除时，是否检测对象的有效性

		poolingContextSource.setMaxActive(maxActive <= 0 ? 20:maxActive);
		poolingContextSource.setMaxTotal(maxTotal <= 0 ? 40:maxTotal);
		poolingContextSource.setMaxIdle(maxIdle <= 0 ? 5:maxIdle);
		poolingContextSource.setMinIdle(minIdle <= 0 ? 5:minIdle);
		poolingContextSource.setMaxWait(maxWait <= 0 ? 5:maxWait);

		TransactionAwareContextSourceProxy proxy = new TransactionAwareContextSourceProxy(poolingContextSource);
		return proxy;
	}

	@Bean
	public LdapTemplate ldapTemplate() {
		if (null == ldapTemplate)
			ldapTemplate = new LdapTemplate(poolingLdapContextSource());
		return ldapTemplate;
	}

}
